#include "gd32f30x.h"
#include "stdint.h"
#include "stdio.h"
#include "DevicesBeep.h"



/* 周期调用计数（调用频率为10k） */
volatile static uint32_t st_uiBeepTickCnt = 0;

static BeepInfoType st_typeBeepInfo;


void vBeepInit(void)
{
    timer_oc_parameter_struct timer_ocintpara = {0};
    timer_parameter_struct timer_initpara = {0};

    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_TIMER3);

    /*Configure TIMERx CHx as alternate function*/
    gpio_init(BEEP_CHANNEL1_GPIO_Port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, BEEP_CHANNEL1_Pin);


    timer_deinit(BEEP_TIMER);

    /* TIMER1 configuration */
    timer_initpara.prescaler         = 1 - 1;
    timer_initpara.period            = BEEP_PERIOD - 1;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(BEEP_TIMER, &timer_initpara);

    /* CH0,CH1 and CH2 configuration in PWM mode */
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
    timer_channel_output_config(BEEP_TIMER, BEEP_TIMER_CHANNEL, &timer_ocintpara);

    /* CH0 configuration in PWM mode0,duty cycle 0% */
    timer_channel_output_pulse_value_config(BEEP_TIMER, BEEP_TIMER_CHANNEL, 0);
    timer_channel_output_mode_config(BEEP_TIMER, BEEP_TIMER_CHANNEL, TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(BEEP_TIMER, BEEP_TIMER_CHANNEL, TIMER_OC_SHADOW_DISABLE);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(BEEP_TIMER);
    /* auto-reload preload enable */
    timer_enable(BEEP_TIMER);


    /* 初始化后关闭全部蜂鸣器 */
    vBeepStatusSet(BEEP_CHANNEL_ALL, BEEP_FLASH_SLOW_DISABLE_CNT, 1);
    vBeepModeSet(BEEP_CHANNEL_ALL, BEEP_MODE_NORMAL);
}

static void vBeepOpen(uint16_t usChannel)
{
    /* 50% 的占空比声音最响 */
    if(usChannel & BEEP_CHANNEL1)
        timer_channel_output_pulse_value_config(BEEP_TIMER, BEEP_TIMER_CHANNEL, TIMER_CAR(BEEP_TIMER) * 0.5f);
}

static void vBeepClose(uint16_t usChannel)
{
    if(usChannel & BEEP_CHANNEL1)
        timer_channel_output_pulse_value_config(BEEP_TIMER, BEEP_TIMER_CHANNEL, 0);
}

/*
 * Return:      void
 * Parameters:  usChannel: 通道; enumStatus: 状态; ucFlashCnt: 次数;
 * Description: 设置状态
 */
void vBeepStatusSet(BeepChannelEnum usChannel, BeepStateEnum enumStatus, uint8_t ucFlashCnt)
{
    if(usChannel & BEEP_CHANNEL1)
    {
        st_typeBeepInfo.channel1.state = enumStatus;
        st_typeBeepInfo.channel1.flashCnt = ucFlashCnt * 2 - 1;
    }

    /* 重新开始计时，以达到完整的声音周期 */
    st_uiBeepTickCnt = 0;
}

/*
 * Return:      void
 * Parameters:  usChannel: 通道; enumMode: 模式;
 * Description: 设置模式
 */
void vBeepModeSet(BeepChannelEnum usChannel, BeepModeEnum enumMode)
{
    if(usChannel & BEEP_CHANNEL1)
    {
        st_typeBeepInfo.channel1.mode = enumMode;
    }
}

/*
 * Return:      void
 * Parameters:  *ptypeBEEP: BEEP信息结构体
 * Description: BEEP状态刷新
 */
static void vBeepStateMachine(BeepType *ptypeBEEP)
{
    switch(ptypeBEEP->state)
    {
        /* 关闭 */
        case BEEP_DISABLE:
            vBeepClose(BEEP_CHANNEL1);
            ptypeBEEP->state = BEEP_IDLE;
            break;

        /* 常响 */
        case BEEP_ENABLE:
            vBeepOpen(BEEP_CHANNEL1);
            ptypeBEEP->state = BEEP_IDLE;
            break;

        /* 快闪/快闪后关闭/快闪后常响 */
        case BEEP_FLASH_SLOW:
        case BEEP_FLASH_SLOW_DISABLE_CNT:
        case BEEP_FLASH_SLOW_ENABLE_CNT:
            if((st_uiBeepTickCnt % 5) == 0)
            {
                ((st_uiBeepTickCnt / 5) & 1) ? vBeepOpen(BEEP_CHANNEL1) : vBeepClose(BEEP_CHANNEL1);

                if((ptypeBEEP->state != BEEP_FLASH_SLOW) && ((ptypeBEEP->flashCnt--) <= 0))
                {
                    ptypeBEEP->state = (ptypeBEEP->state == BEEP_FLASH_SLOW_ENABLE_CNT) ? BEEP_ENABLE : BEEP_DISABLE;
                }
            }
            break;

        /* 慢闪/慢闪后关闭/慢闪后常响 */
        case BEEP_FLASH_FAST:
        case BEEP_FLASH_FAST_DISABLE_CNT:
        case BEEP_FLASH_FAST_ENABLE_CNT:
            (st_uiBeepTickCnt & 1) ? vBeepOpen(BEEP_CHANNEL1) : vBeepClose(BEEP_CHANNEL1);

            if((ptypeBEEP->state != BEEP_FLASH_FAST) && ((ptypeBEEP->flashCnt--) <= 0))
            {
                ptypeBEEP->state = (ptypeBEEP->state == BEEP_FLASH_FAST_ENABLE_CNT) ? BEEP_ENABLE : BEEP_DISABLE;
            }
            break;

        default : break;
    }
}

/* 100ms调用一次 */
void vBeepMachine(void)
{
    ++st_uiBeepTickCnt;

    /* 非静音模式 */
    if(st_typeBeepInfo.channel1.mode == BEEP_MODE_NORMAL)
    {
        vBeepStateMachine(&st_typeBeepInfo.channel1);
    }
    /* 静音模式 */
    else
    {
        vBeepClose(BEEP_CHANNEL1);
    }
}

BeepInfoType *ptypeBeepInfoGet(void)
{
    return &st_typeBeepInfo;
}
